﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using STHPMS1.Common.C_Entity;
using STHPMS1.Common.C_Entity.Stmpms1;
using STHPMS1.ICore;
using STHPMS1.ICore.I_Core;
using STHPMS1.ICore.I_Serv;
using STHPMS1.ICore.I_UI;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using System.IO;
using System.Reflection;
using STHPMS1.Common.C_Extension;

namespace STHPMS1.Web.W_Controller.Basis
{
    [RoutePrefix("api/history")]
    public class B_HistoryController : STHPMS1.Web.W_Core.MyController
    {
        #region 导入处理

        /// <summary>
        /// 检查并保存冲突的路面结构ID
        /// </summary>
        /// <param name="originalData"></param>
        /// <param name="histroyStruid"></param>
        private void SaveHistory(DataTable originalData, Dictionary<string, List<B_Pmstc>> histroy)
        {
            foreach (DataRow dr in originalData.Rows)
            {
                IEnumerable<B_Pmstc> original = this.Scene.Bll.B_History.GetPMSTC<B_Pmstc>(dr["RDWAYID"].ToString(), Convert.ToInt32(dr["DIRECTION_DICTID"]));
                double start = Convert.ToDouble(dr["BEGINMP"]);
                double end = Convert.ToDouble(dr["ENDMP"]);
                List<B_Pmstc> histroyStruid = new List<B_Pmstc>();
                //遍历排序后的路面结构
                foreach (B_Pmstc old in original)
                {
                    if (old.Beginmp > start || old.Endmp < end)
                    {
                        histroyStruid.Add(old);
                    }
                    else if (old.Beginmp < start && old.Endmp > end)
                    {
                        histroyStruid.Add(old);
                    }
                    else if (old.Beginmp == start && old.Endmp == end)
                    {
                        histroyStruid.Add(old);
                    }
                }
                histroy.Add(start + "_" + end, histroyStruid);
            }
        }

        /// <summary>
        /// 移动处理冲突的路面结构
        /// </summary>
        /// <param name="histroy"></param>
        private void MoveHistory(Dictionary<string, List<B_Pmstc>> histroy)
        {
            foreach (KeyValuePair<string, List<B_Pmstc>> kv in histroy)
            {
                string[] mp = kv.Key.Split('_'); //起点和终点桩号
                double start = Convert.ToDouble(mp[0]);
                double end = Convert.ToDouble(mp[1]);
                //遍历冲突的路面结构
                foreach (B_Pmstc old in kv.Value)
                {
                    if (old.Beginmp < start && (old.Endmp > start && old.Endmp < end)) //结束桩号在中间
                    {
                        //将old的Endmp改为start
                        this.Scene.Bll.B_History.UpdateEndmp(old.Struid, start);
                    }
                    else if ((old.Beginmp > start && old.Beginmp < end) && old.Endmp > end) //起始桩号在中间
                    {
                        //将old的Beginmp改为end,修改结构ID和层的结构ID
                        string oldID = old.Struid;
                        string newID = "JG" + "_" + old.Rdwayid + "_" + end + "_" + old.Direction_Dictid;
                        this.Scene.Bll.B_History.UpdateHistory(oldID, newID, end);
                    }
                    else if (old.Beginmp < start && old.Endmp > end) //起始结束桩号包含导入桩号
                    {
                        //将old的Endmp改为start
                        this.Scene.Bll.B_History.UpdateEndmp(old.Struid, start);
                        //增加一个新的路面结构，从旧路面结构拆分一个
                        string oldID = old.Struid;
                        string newID = "JG" + "_" + old.Rdwayid + "_" + end + "_" + old.Direction_Dictid;
                        old.Struid = newID;
                        old.Beginmp = end;
                        this.Scene.Bll.B_History.AddNewData(oldID, old);
                    }
                    else if (old.Beginmp >= start && old.Endmp <= end) //导入桩号包含起始结束桩号
                    {
                        //删除现有结构和层，移动到历史表
                        this.Scene.Bll.B_History.MoveOldData(old.Struid);
                    }
                }
            }
        }

        /// <summary>
        /// 上传数据处理
        /// </summary>
        /// <param name="file">文件路径</param>
        /// <returns></returns>
        [Route("saveFile")]
        public HttpResponseMessage PostSaveFile(string file)
        {
            if (File.Exists(file))
            {
                try
                {
                    int startRow = 0;//Excel列头位置
                    DataTable excel = Common.C_Excel.ExcelTool.RenderDataTableFromExcel(file, startRow);//获取Excel的DataTable
                    //创建结构表和层表
                    DataTable dt_PMSTC = this.Scene.Bll.B_Pmstc.GetEmptyData();
                    DataTable dt_LAYER = this.Scene.Bll.B_Pmstc.GetLayerEmptyData();
                    CreateData(excel, dt_PMSTC, dt_LAYER);
                    //和养护历史进行比对,筛选出历史数据
                    Dictionary<string, List<B_Pmstc>> histroyData = new Dictionary<string, List<B_Pmstc>>();
                    //保存数据库中冲突的路面结构(历史版本)
                    SaveHistory(dt_PMSTC, histroyData);
                    //移动更新历史路面结构
                    MoveHistory(histroyData);
                    //导入
                    this.Scene.Bll.Excel.ImportAll("B_PMSTC", dt_PMSTC, "B_LAYER", dt_LAYER);
                }
                catch (Exception ex)
                {
                    File.Delete(file);//删除上传数据
                    //抛出错误
                    var response = new HttpResponseMessage(HttpStatusCode.InternalServerError)
                    {
                        Content = new StringContent(ex.Message),
                        ReasonPhrase = "Server Error"
                    };
                    throw new HttpResponseException(response);
                }
            }
            else
            {
                //抛出错误
                var response = new HttpResponseMessage(HttpStatusCode.InternalServerError)
                {
                    Content = new StringContent("服务器未能保存上传文件，请联系管理员"),
                    ReasonPhrase = "Server Error"
                };
                throw new HttpResponseException(response);
            }
            var res = Request.CreateResponse(HttpStatusCode.Created);
            // Generate a link to the new book and set the Location header in the response.
            string uri = Url.Link("GetpmstcByPage", new { page = 1 });
            res.Headers.Location = new Uri(uri);

            return res;
        }

        /// <summary>
        /// 反射获取对象的所有属性
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        private PropertyInfo[] GetAllProperty(object t)
        {
            Type temp = t.GetType();
            return temp.GetProperties();
        }

        #region 字典和验证字典
        /// <summary>
        /// 得到基层类型
        /// </summary>
        /// <param name="k"></param>
        /// <returns></returns>
        private int? GetBASICTYPE_DICTID(string k)
        {
            if (Common.C_Enum.RoadBasicTypeEnum.B165.GetEnumDescription() == k) return 165;
            else if (Common.C_Enum.RoadBasicTypeEnum.B166.GetEnumDescription() == k) return 166;
            else if (Common.C_Enum.RoadBasicTypeEnum.B167.GetEnumDescription() == k) return 167;
            else if (Common.C_Enum.RoadBasicTypeEnum.B171.GetEnumDescription() == k) return 171;
            else if (Common.C_Enum.RoadBasicTypeEnum.B172.GetEnumDescription() == k) return 172;
            else if (Common.C_Enum.RoadBasicTypeEnum.B173.GetEnumDescription() == k) return 173;
            else if (Common.C_Enum.RoadBasicTypeEnum.B174.GetEnumDescription() == k) return 174;
            return null;
        }

        /// <summary>
        /// 得到面层类型
        /// </summary>
        /// <param name="k"></param>
        /// <returns></returns>
        private int GetPVMTTYPE_DICTID(string k)
        {
            if (Common.C_Enum.PavementTypeEnum.P21.GetEnumDescription() == k) return 21;
            else if (Common.C_Enum.PavementTypeEnum.P22.GetEnumDescription() == k) return 22;
            else if (Common.C_Enum.PavementTypeEnum.P23.GetEnumDescription() == k) return 23;
            return -1;
        }

        /// <summary>
        /// 层位
        /// </summary>
        /// <param name="k"></param>
        /// <returns></returns>
        private int GetLayer_Dictid(string k)
        {
            if (Common.C_Enum.LayerEnum.L100.GetEnumDescription() == k) return 100;
            else if (Common.C_Enum.LayerEnum.L30.GetEnumDescription() == k) return 30;
            else if (Common.C_Enum.LayerEnum.L45.GetEnumDescription() == k) return 45;
            else if (Common.C_Enum.LayerEnum.L50.GetEnumDescription() == k) return 50;
            else if (Common.C_Enum.LayerEnum.L55.GetEnumDescription() == k) return 55;
            else if (Common.C_Enum.LayerEnum.L75.GetEnumDescription() == k) return 75;
            else if (Common.C_Enum.LayerEnum.L95.GetEnumDescription() == k) return 95;
            return -1;
        }

        /// <summary>
        /// 验证各层面对应材料
        /// </summary>
        /// <param name="LAYER_DICTID"></param>
        /// <param name="STRU_ID"></param>
        private void CheckSTRU_ID(int LAYER_DICTID, string STRU_ID)
        {
            if (LAYER_DICTID == Common.C_Enum.LayerEnum.L30.GetEnumValue()) //上面层
            {
                if ("AC-10,改性AC-10,AC-13,AC-16,改性AC-13,改性AC-16,sup-13，SMA-13,SMA-16，OGFC-13，OGFC-16，AM-16,AM-20，AM-25，ARAC-13,ARAC-20,ARAC-25，沥青贯入式，水泥混凝土板".IndexOf(STRU_ID) == -1)
                {
                    throw new Exception("上面层不存在[" + STRU_ID + "]材料");
                }
            }
            else if (LAYER_DICTID == Common.C_Enum.LayerEnum.L45.GetEnumValue())//中面层
            {
                if ("AC-16,AC-20,改性AC-16,改性AC-20,sup-19，sup-25，AM-16,AM-20，AM-25".IndexOf(STRU_ID) == -1)
                {
                    throw new Exception("中面层不存在[" + STRU_ID + "]材料");
                }
            }
            else if (LAYER_DICTID == Common.C_Enum.LayerEnum.L50.GetEnumValue())//下面层
            {
                if ("AC-20,AC-25,sup-25,改性AC-20,改性AC-25,AM-20，AM-25".IndexOf(STRU_ID) == -1)
                {
                    throw new Exception("下面层不存在[" + STRU_ID + "]材料");
                }
            }
            else if (LAYER_DICTID == Common.C_Enum.LayerEnum.L55.GetEnumValue())//基层
            {
                if ("水泥稳定碎石,水泥稳定砂砾,水泥稳定土,石灰稳定碎石,石灰稳定砂砾,石灰土,二灰碎石,二灰砂砾,二灰土,石灰工业废渣稳定碎石,石灰工业废渣稳定砂砾,石灰工业废渣稳定土,ATB-25,ATB-30,LSM-30,LSM-35，LSM-30,LSM-35,AM-16,AM-20，AM-25，级配砾石,级配碎石,天然砂砾,级配碎砾石,泥结碎石,泥灰结碎石,填隙碎石".IndexOf(STRU_ID) == -1)
                {
                    throw new Exception("基层不存在[" + STRU_ID + "]材料");
                }
            }
            else if (LAYER_DICTID == Common.C_Enum.LayerEnum.L75.GetEnumValue())//底基层
            {
                if ("水泥稳定碎石,水泥稳定砂砾,水泥稳定土 ,石灰稳定碎石,石灰稳定砂砾，石灰土,二灰碎石,二灰砂砾,二灰土 ,石灰工业废渣稳定碎石,石灰工业废渣稳定砂砾,石灰工业废渣稳定土,ATB-25,ATB-30，LSM-30,LSM-35，AM-16，AM-20，AM-25，LSM-30,LSM-35，级配砾石,级配碎石,天然砂砾,级配碎砾石,泥结碎石,泥灰结碎石,填隙碎石".IndexOf(STRU_ID) == -1)
                {
                    throw new Exception("底基层不存在[" + STRU_ID + "]材料");
                }
            }
            else if (LAYER_DICTID == Common.C_Enum.LayerEnum.L95.GetEnumValue())//垫层
            {
                if ("级配砾石,级配碎石,天然砂砾,级配碎砾石,泥结碎石,泥灰结碎石,填隙碎石".IndexOf(STRU_ID) == -1)
                {
                    throw new Exception("垫层不存在[" + STRU_ID + "]材料");
                }
            }
        }

        #endregion

        /// <summary>
        /// 添加路面结构和层表
        /// </summary>
        /// <param name="excel"></param>
        /// <param name="dt_PMSTC"></param>
        /// <param name="dt_LAYER"></param>
        private void CreateData(DataTable excel, DataTable dt_PMSTC, DataTable dt_LAYER)
        {
            List<string> temp = new List<string>();//验证路面结构是否重复
            string importDate = DateTime.Now.ToShortDateString();//导入时间

            foreach (DataRow dr in excel.Rows)
            {
                string _rdid = dr[0].ToString();//路线 
                double version = this.Scene.Bll.B_Roadway.GetNewHistoryVersion(_rdid,true);//版本号
                int dir = -1; //方向
                if (Common.C_Enum.DirectionEnum.Up11.GetEnumDescription() == dr[1].ToString()) dir = 11;
                else if (Common.C_Enum.DirectionEnum.Down12.GetEnumDescription() == dr[1].ToString()) dir = 12;
                else if (Common.C_Enum.DirectionEnum.All13.GetEnumDescription() == dr[1].ToString()) dir = 13;
                double start = Convert.ToDouble(dr[2]);//起点
                double end = Convert.ToDouble(dr[3]);//终点
                string _STRUID = "JG" + "_" + _rdid + "_" + start + "_" + dir;//路面结构编号
                int _PVMTTYPE_DICTID = GetPVMTTYPE_DICTID(dr[4].ToString());//面层类型               
                int? _BASICTYPE_DICTID = GetBASICTYPE_DICTID(dr[5].ToString());//基层类型
                double _cbr = Convert.ToDouble(dr[6]);//CRB
                double _DEGDF = Convert.ToDouble(dr[7]);//设计弯沉
                double _THICK = Convert.ToDouble(dr[8]);//总厚度

                if (!temp.Contains(_STRUID))
                {
                    //构建路面结构的一行
                    DataRow pmstcRow = dt_PMSTC.NewRow();
                    pmstcRow["STRUID"] = _STRUID;
                    pmstcRow["RDWAYID"] = _rdid;
                    pmstcRow["BEGINMP"] = start;
                    pmstcRow["ENDMP"] = end;
                    pmstcRow["DIRECTION_DICTID"] = dir;
                    pmstcRow["PVMTTYPE_DICTID"] = _PVMTTYPE_DICTID;
                    pmstcRow["BASICTYPE_DICTID"] = _BASICTYPE_DICTID;
                    pmstcRow["CBR"] = _cbr;
                    pmstcRow["DEGDF"] = _DEGDF;
                    pmstcRow["THICK"] = _THICK;
                    pmstcRow["IMPORTDATE"] = importDate;
                    pmstcRow["HIS_VERSION"] = version;
                    dt_PMSTC.Rows.Add(pmstcRow);

                    temp.Clear();
                    temp.Add(_STRUID);
                }
                int _LAYER_DICTID = GetLayer_Dictid(dr[9].ToString());//层位
                string _STRU_ID = dr[10].ToString();//结构层材料 Excel对应
                //验证层材料是否正确
                CheckSTRU_ID(_LAYER_DICTID, _STRU_ID);
                double _LayTHICK = Convert.ToDouble(dr[11]);//厚度
                double _POIRAT = Convert.ToDouble(dr[12]);//泊松比
                double _ELAMOD = Convert.ToDouble(dr[13]);//回弹模量
                double _LAYERCOEFF = Convert.ToDouble(dr[14]);//层系数
                double _DRAINCOEFF = Convert.ToDouble(dr[15]);//排水系数
                string _LayId = _STRUID + "_" + _LAYER_DICTID;//层ID
                DataRow layerRow = dt_LAYER.NewRow();
                layerRow["LAYID"] = _LayId;
                layerRow["RDWAYID"] = _rdid;
                layerRow["STRUID"] = _STRUID;
                layerRow["LAYER_DICTID"] = _LAYER_DICTID;
                layerRow["STRU_ID"] = _STRU_ID;
                layerRow["THICK"] = _LayTHICK;
                layerRow["POIRAT"] = _POIRAT;
                layerRow["ELAMOD"] = _ELAMOD;
                layerRow["LAYERCOEFF"] = _LAYERCOEFF;
                layerRow["DRAINCOEFF"] = _DRAINCOEFF;
                layerRow["DIRECTION_DICTID"] = dir;
                layerRow["IMPORTDATE"] = importDate;
                layerRow["HIS_VERSION"] = version;
                dt_LAYER.Rows.Add(layerRow);
            }
        }

        /// <summary>
        /// 上传返回上传后路径
        /// </summary>
        [Route("uploadFile")]
        public void PostUploadFile()
        {

            System.Web.HttpFileCollection hfc = System.Web.HttpContext.Current.Request.Files;
            string uploadPath =
              System.Web.HttpContext.Current.Server.MapPath("~/App_Data/Upload") + "\\";
            string PhysicalPath = "";
            if (hfc.Count > 0)
            {
                if (!Directory.Exists(uploadPath))
                {
                    Directory.CreateDirectory(uploadPath);
                }
                PhysicalPath = uploadPath + hfc[0].FileName;
                hfc[0].SaveAs(PhysicalPath);
            }

            System.Web.HttpContext.Current.Response.Write(PhysicalPath);
            System.Web.HttpContext.Current.Response.End();
        }
        #endregion


        #region 查询和添加

        /// <summary>
        /// 默认查询
        /// </summary>
        /// <param name="page"></param>
        /// <param name="rows"></param>
        /// <returns></returns>
        [Route("")]
        [Route("page/{page?}", Name = "GetHistoryByPage")]
        [Route("rows/{rows?}")]
        [Route("page/{page?}/rows/{rows?}")]
        public IHttpActionResult Get(int page = 1, int rows = 10)
        {
            int p = page;
            int s = rows;

            PagingInfo info = new PagingInfo();
            info.PageIndex = p > 0 ? p - 1 : 0;
            info.PageSize = s;
            info.TotalRecords = 0;

            var data = this.Scene.Bll.B_History.Get<B_History_Details>(null, info).ToArray();
            if (data == null) return NotFound();

            var result = new { rows = data, total = info.TotalRecords };

            return Ok(result);
        }

        [Route("details")]
        public IHttpActionResult Get(string id = null, int page = 1, int rows = 10)
        {
            int p = page;
            int s = rows;

            PagingInfo info = new PagingInfo();
            info.PageIndex = p > 0 ? p - 1 : 0;
            info.PageSize = s;
            info.TotalRecords = 0;

            var data = this.Scene.Bll.B_History.GetDetails<B_History_Layer_Details>(null, info, id).ToArray();
            if (data == null) return NotFound();

            var result = new { rows = data, total = info.TotalRecords };

            return Ok(result);
        }

        [Route("searchRoad")]
        public IHttpActionResult GetRoad()
        {
            return Ok(this.Scene.Bll.B_Roadway.GetAll<B_Roadway>());
        }

        /// <summary>
        /// 保存养护历史
        /// </summary>
        [Route("save")]
        public IHttpActionResult PostSaveHistory(string rdid, string dir, string year, string start, string end, string v,string yh)
        {
            try
            {
                string guid = Guid.NewGuid().ToString();
                B_History_Details h_d = new B_History_Details();
                h_d.Detailsid = guid;
                h_d.Rdwayid = rdid;
                h_d.Direction_Dictid = int.Parse(dir);
                h_d.Beginmp = double.Parse(start);
                h_d.Endmp = double.Parse(end);
                h_d.Year = int.Parse(year);
                h_d.Pave_Type = int.Parse(yh);//养护类型
                h_d.His_Version = this.Scene.Bll.B_Roadway.GetNewHistoryVersion(rdid, false);//历史版本

                List<B_History_Layer_Details> lstLayerDetails = new List<B_History_Layer_Details>();

                double begmp = Convert.ToDouble(start);//起始桩号
                double endmp = Convert.ToDouble(end);//结束桩号
                List<LayerTemp> layerTemp = new List<LayerTemp>();//层的养护历史
                string[] vs = v.Substring(0, v.Length - 1).Split('|');//包括层类型*铣刨厚度*加铺厚度*加铺材料
                foreach (string s in vs)
                {
                    string[] temps = s.Split('*');
                    LayerTemp _l = new LayerTemp();
                    _l.LAYER_DICTID = Convert.ToInt32(temps[0]);
                    //层位验证
                    CheckLayer(rdid, int.Parse(dir), _l.LAYER_DICTID);
                    _l.XPTHICK = Convert.ToDouble(temps[1]); 
                    _l.JPTHICK = Convert.ToDouble(temps[2]);
                    _l.JPCL = temps[3] == "请选择" ? "" : temps[3];
                    layerTemp.Add(_l);
                }
                //根据路线和方向查询匹配的路面结构
                //IEnumerable<B_Pmstc> original = this.Scene.Bll.B_History.GetPMSTC<B_Pmstc>(rdid, Convert.ToInt32(dir));
                //B_Pmstc tempPmstc = null;
                //foreach (B_Pmstc p in original)
                //{
                //    if (p.Beginmp <= begmp && p.Endmp >= endmp)
                //    {
                //        tempPmstc = p;
                //        break;
                //    }
                //}
                List<B_Pmstc> tempPmstcs = GetClashPMSTC(rdid, dir, begmp, endmp);

                if (tempPmstcs.Count == 0)
                {
                    throw new Exception("系统没有找到对应的路面结构");
                }
                double version = this.Scene.Bll.B_Roadway.GetNewHistoryVersion(rdid,true);//版本号
                foreach (B_Pmstc tempPmstc in tempPmstcs)
                {
                    //查询该路面结构对应的层
                    IEnumerable<B_Layer> layers = this.Scene.Bll.B_History.GetLayer<B_Layer>(tempPmstc.Struid);
                    if (tempPmstc.Beginmp >= begmp && tempPmstc.Endmp <= endmp) //起终桩号包含原始结构或者起点和终点桩号相同----------------------------------------------------------------------------
                    {
                        double? sumThick = 0; //层总厚度
                        double? sumThick_S = 0;//面层厚度
                       
                        foreach (B_Layer b in layers)
                        {
                            foreach (LayerTemp t in layerTemp)
                            {
                                if (b.Layer_Dictid == t.LAYER_DICTID)
                                {
                                    //养护历史记录
                                    B_History_Layer_Details h_l_d = new B_History_Layer_Details();
                                    h_l_d.Detailsid = guid;
                                    h_l_d.Layer_Dictid = b.Layer_Dictid;
                                    h_l_d.MillingThick = t.XPTHICK;
                                    h_l_d.OverLayThick = t.JPTHICK;
                                    h_l_d.Stru_Id = t.JPCL;
                                    h_l_d.History_LayerId = b.Layid;
                                    lstLayerDetails.Add(h_l_d);

                                    b.Thick = b.Thick + t.XPTHICK + t.JPTHICK;//层厚度
                                    b.Stru_Id = t.JPCL == "" ? b.Stru_Id : t.JPCL;//加铺材料
                                }
                            }
                            b.His_Version = version;//版本号
                            sumThick += b.Thick;//总厚度
                            if (b.Layer_Dictid < 55)
                            {
                                sumThick_S += b.Thick;//计算面层总厚度
                            }
                        }
                        tempPmstc.His_Version = version;//路面结构的版本号
                        tempPmstc.Thick_T = sumThick;//结构层总厚度
                        tempPmstc.Thick_S = sumThick_S;//面层总厚度
                        //更新路面结构和对应的层
                        this.Scene.Bll.B_History.UpdateXTHistroy(tempPmstc, layers.ToArray());
                    }

                    else if (tempPmstc.Beginmp < begmp && tempPmstc.Endmp > endmp) //起终桩号被原始结构包含--------------------------------------------------------------------
                    {
                        string oldStruid = tempPmstc.Struid;//老的结构ID
                        //double version = this.Scene.Bll.B_Roadway.GetNewHistoryVersion(rdid);//版本号
                        List<B_Pmstc> newPmstc = new List<B_Pmstc>();
                        List<B_Layer> newLayer = new List<B_Layer>();
                        //创建3个路面结构,1个只需更改终点桩号,2个新创建,3个更改起始桩号(结构ID和层对应的结构ID)，养护版本
                        B_Pmstc p1 = CopyPmstc(tempPmstc);//第1段
                        p1.Endmp = begmp;
                        p1.His_Version = version;
                        foreach (B_Layer oldChild in layers)//第1段路面结构对应的层
                        {
                            B_Layer ly3 = CopyLayer(oldChild);
                            ly3.His_Version = version;
                            newLayer.Add(ly3);
                        }
                        newPmstc.Add(p1);//第1段路面结构

                        B_Pmstc p3 = CopyPmstc(tempPmstc);//第3段
                        p3.Struid = "JG_" + p3.Rdwayid + "_" + endmp + "_" + p3.Direction_Dictid;
                        p3.Beginmp = endmp;
                        p3.Endmp = tempPmstc.Endmp;
                        p3.His_Version = version;
                        foreach (B_Layer oldChild in layers)//第3段路面结构对应的层
                        {
                            B_Layer ly3 = CopyLayer(oldChild);
                            ly3.Layid = p3.Struid + "_" + ly3.Layer_Dictid;
                            ly3.Struid = p3.Struid;//层对应的结构ID
                            ly3.His_Version = version;
                            newLayer.Add(ly3);
                        }
                        newPmstc.Add(p3);//第3段路面结构

                        B_Pmstc p2 = CopyPmstc(tempPmstc);//第2段
                        p2.Struid = "JG_" + p2.Rdwayid + "_" + begmp + "_" + p2.Direction_Dictid;
                        p2.Beginmp = begmp;
                        p2.Endmp = endmp;
                        p2.His_Version = version;
                        double? sumThick = 0;//结构层总厚度
                        double? sumThick_S = 0;//面层厚度
                        foreach (B_Layer oldChild in layers)//第2段路面结构对应的层
                        {
                            B_Layer ly3 = CopyLayer(oldChild);
                            ly3.Struid = p2.Struid;
                            ly3.Layid = p2.Struid + "_" + ly3.Layer_Dictid;
                            ly3.His_Version = version;
                            foreach (LayerTemp t in layerTemp)//层有变化
                            {
                                if (ly3.Layer_Dictid == t.LAYER_DICTID)
                                {
                                    ly3.Stru_Id = t.JPCL;
                                    //养护历史记录
                                    B_History_Layer_Details h_l_d = new B_History_Layer_Details();
                                    h_l_d.Detailsid = guid;
                                    h_l_d.Layer_Dictid = ly3.Layer_Dictid;
                                    h_l_d.MillingThick = t.XPTHICK;
                                    h_l_d.OverLayThick = t.JPTHICK;
                                    h_l_d.Stru_Id = t.JPCL;
                                    h_l_d.History_LayerId = oldChild.Layid;
                                    lstLayerDetails.Add(h_l_d);

                                    ly3.Thick = ly3.Thick + t.XPTHICK + t.JPTHICK;//层厚度
                                    ly3.Stru_Id = t.JPCL == "" ? ly3.Stru_Id : t.JPCL;//加铺材料
                                }
                            }
                            newLayer.Add(ly3);
                            sumThick += ly3.Thick;//计算结构层总厚度
                            if (ly3.Layer_Dictid < 55)
                            {
                                sumThick_S += ly3.Thick;//计算面层总厚度
                            }
                        }
                        p2.Thick_T = sumThick;//层总厚度
                        p2.Thick_S = sumThick_S;//面层总厚度
                        newPmstc.Add(p2);//第2段路面结构

                        //更新路面结构和对应的层
                        this.Scene.Bll.B_History.UpdateHistory(oldStruid, newPmstc.ToArray(), newLayer.ToArray());
                    }
                    //输入终点桩号在原始桩号之间，输入起点桩号在外
                    //或者
                    //起始桩号相同,原始结束桩号大于输入桩号-------------------------------------------------------------------------------
                    else if ((tempPmstc.Beginmp == begmp && tempPmstc.Endmp > endmp) ||
                        ((endmp > tempPmstc.Beginmp && endmp < tempPmstc.Endmp) && begmp < tempPmstc.Beginmp))
                    {
                        string oldStruid = tempPmstc.Struid;//老的结构ID
                        //double version = this.Scene.Bll.B_Roadway.GetNewHistoryVersion(rdid);//版本号
                        List<B_Pmstc> newPmstc = new List<B_Pmstc>();
                        List<B_Layer> newLayer = new List<B_Layer>();
                        //创建2个路面结构,1个新创建,2个更改起始桩号(结构ID和层对应的结构ID)，养护版本
                        B_Pmstc p1 = CopyPmstc(tempPmstc);//第1段
                        p1.Endmp = endmp;
                        p1.His_Version = version;
                        double? sumThick = 0;//结构层总厚度
                        double? sumThick_S = 0;//面层厚度
                        foreach (B_Layer oldChild in layers)//第1段路面结构对应的层
                        {
                            B_Layer ly3 = CopyLayer(oldChild);
                            ly3.His_Version = version;
                            foreach (LayerTemp t in layerTemp)//层有变化
                            {
                                if (ly3.Layer_Dictid == t.LAYER_DICTID)
                                {
                                    //养护历史记录
                                    B_History_Layer_Details h_l_d = new B_History_Layer_Details();
                                    h_l_d.Detailsid = guid;
                                    h_l_d.Layer_Dictid = ly3.Layer_Dictid;
                                    h_l_d.MillingThick = t.XPTHICK;
                                    h_l_d.OverLayThick = t.JPTHICK;
                                    h_l_d.Stru_Id = t.JPCL;
                                    h_l_d.History_LayerId = oldChild.Layid;
                                    lstLayerDetails.Add(h_l_d);

                                    ly3.Thick = ly3.Thick + t.XPTHICK + t.JPTHICK;//层厚度
                                    ly3.Stru_Id = t.JPCL == "" ? ly3.Stru_Id : t.JPCL;//加铺材料
                                }
                            }
                            newLayer.Add(ly3);
                            sumThick += ly3.Thick;
                            if (ly3.Layer_Dictid < 55)
                            {
                                sumThick_S += ly3.Thick;//计算面层总厚度
                            }
                        }
                        p1.Thick_T = sumThick;//层总厚度
                        p1.Thick_S = sumThick_S;//面层总厚度
                        newPmstc.Add(p1);//第1段路面结构

                        B_Pmstc p2 = CopyPmstc(tempPmstc);//第2段
                        p2.Struid = "JG_" + p2.Rdwayid + "_" + endmp + "_" + p2.Direction_Dictid;
                        p2.Beginmp = endmp;
                        p2.Endmp = tempPmstc.Endmp;
                        p2.His_Version = version;
                        foreach (B_Layer oldChild in layers)//第2段路面结构对应的层
                        {
                            B_Layer ly3 = CopyLayer(oldChild);
                            ly3.Layid = p2.Struid + "_" + ly3.Layer_Dictid;
                            ly3.Struid = p2.Struid; //层的结构ID
                            ly3.His_Version = version;
                            newLayer.Add(ly3);
                        }
                        newPmstc.Add(p2);//第2段路面结构
                        //更新路面结构和对应的层
                        this.Scene.Bll.B_History.UpdateHistory(oldStruid, newPmstc.ToArray(), newLayer.ToArray());
                    }
                    //输入起点桩号在原始桩号之间，输入终点桩号在原始桩号之外                 
                    // 或者
                    //终点桩号相同,原始起始桩号小于输入桩号---------------------------------------------------------------------------------
                    else if ((tempPmstc.Beginmp < begmp && tempPmstc.Endmp == endmp) ||
                        ((begmp > tempPmstc.Beginmp && begmp < tempPmstc.Endmp) && endmp > tempPmstc.Endmp))
                    {
                        string oldStruid = tempPmstc.Struid;//老的结构ID
                        //double version = this.Scene.Bll.B_Roadway.GetNewHistoryVersion(rdid);//版本号
                        List<B_Pmstc> newPmstc = new List<B_Pmstc>();
                        List<B_Layer> newLayer = new List<B_Layer>();
                        B_Pmstc p1 = CopyPmstc(tempPmstc);//第1段
                        p1.Endmp = begmp;
                        p1.His_Version = version;

                        foreach (B_Layer oldChild in layers)//第1段路面结构对应的层
                        {
                            B_Layer ly3 = CopyLayer(oldChild);
                            ly3.His_Version = version;
                            newLayer.Add(ly3);
                        }
                        newPmstc.Add(p1);//第1段路面结构

                        B_Pmstc p2 = CopyPmstc(tempPmstc);//第2段
                        p2.Struid = "JG_" + p2.Rdwayid + "_" + begmp + "_" + p2.Direction_Dictid;
                        p2.Beginmp = begmp;
                        p2.Endmp = tempPmstc.Endmp;
                        p2.His_Version = version;
                        double? sumThick = 0;//结构层总厚度
                        double? sumThick_S = 0;//面层厚度
                        foreach (B_Layer oldChild in layers)//第2段路面结构对应的层
                        {
                            B_Layer ly3 = CopyLayer(oldChild);
                            ly3.His_Version = version;
                            ly3.Layid = p2.Struid + "_" + ly3.Layer_Dictid;
                            ly3.Struid = p2.Struid;
                            foreach (LayerTemp t in layerTemp)//层有变化
                            {
                                if (ly3.Layer_Dictid == t.LAYER_DICTID)
                                {
                                    //养护历史记录
                                    B_History_Layer_Details h_l_d = new B_History_Layer_Details();
                                    h_l_d.Detailsid = guid;
                                    h_l_d.Layer_Dictid = ly3.Layer_Dictid;
                                    h_l_d.MillingThick = t.XPTHICK;
                                    h_l_d.OverLayThick = t.JPTHICK;
                                    h_l_d.Stru_Id = t.JPCL;
                                    h_l_d.History_LayerId = oldChild.Layid;
                                    lstLayerDetails.Add(h_l_d);

                                    ly3.Thick = ly3.Thick + t.XPTHICK + t.JPTHICK;//层厚度
                                    ly3.Stru_Id = t.JPCL == "" ? ly3.Stru_Id : t.JPCL;//加铺材料
                                }
                            }
                            newLayer.Add(ly3);
                            sumThick += ly3.Thick;
                            if (ly3.Layer_Dictid < 55)
                            {
                                sumThick_S += ly3.Thick;//计算面层总厚度
                            }
                        }
                        p2.Thick_T = sumThick;//层总厚度
                        p2.Thick_S = sumThick_S;//面层总厚度
                        newPmstc.Add(p2);//第2段路面结构
                        //更新路面结构和对应的层
                        this.Scene.Bll.B_History.UpdateHistory(oldStruid, newPmstc.ToArray(), newLayer.ToArray());

                    }
                }
                //添加养护记录
                this.Scene.Bll.B_History.AddHistory(h_d, lstLayerDetails.ToArray());
                return Ok("ok");
            }
            catch (Exception ex)
            {
                var response = new HttpResponseMessage(HttpStatusCode.InternalServerError)
                {
                    Content = new StringContent(ex.Message),
                    ReasonPhrase = "Server Error"
                };
                throw new HttpResponseException(response);
            }
        }


        #region 复制和检查对象
        /// <summary>
        /// 复制一个路面结构对象
        /// </summary>
        /// <param name="old"></param>
        /// <returns></returns>
        private B_Pmstc CopyPmstc(B_Pmstc old)
        {
            B_Pmstc temp = new B_Pmstc();
            temp.Struid = old.Struid;
            temp.Rdwayid = old.Rdwayid;
            temp.Beginmp = old.Beginmp;
            temp.Endmp = old.Endmp;
            temp.Direction_Dictid = old.Direction_Dictid;
            temp.Pvmttype_Dictid = old.Pvmttype_Dictid;
            temp.Basictype_Dictid = old.Basictype_Dictid;
            temp.Cbr = old.Cbr;
            temp.Degdf = old.Degdf;
            temp.Thick_T = old.Thick_T;
            temp.Importdate = old.Importdate;
            temp.His_Version = old.His_Version;
            temp.Thick_S = old.Thick_S;
            return temp;
        }

        /// <summary>
        /// 复制一个结构层对象
        /// </summary>
        /// <param name="old"></param>
        /// <returns></returns>
        private B_Layer CopyLayer(B_Layer old)
        {
            B_Layer temp = new B_Layer();
            temp.Layid = old.Layid;
            temp.Rdwayid = old.Rdwayid;
            temp.Struid = old.Struid;
            temp.Layer_Dictid = old.Layer_Dictid;
            temp.Stru_Id = old.Stru_Id;
            temp.Thick = old.Thick;
            temp.Poirat = old.Poirat;
            temp.Elamod = old.Elamod;
            temp.Layercoeff = old.Layercoeff;
            temp.Draincoeff = old.Draincoeff;
            temp.Importdate = old.Importdate;
            temp.His_Version = old.His_Version;
            temp.Direction_Dictid = old.Direction_Dictid;
            return temp;
        }

        /// <summary>
        /// 校验层位类型是否存在
        /// </summary>
        /// <param name="rdid"></param>
        /// <param name="dir"></param>
        /// <param name="layerDictid"></param>
        private void CheckLayer(string rdid, int dir, int layerDictid)
        {
            if (!this.Scene.Bll.B_History.ExistsLayer(rdid, dir, layerDictid))
            {
                if (Common.C_Enum.LayerEnum.L30.GetEnumValue() == layerDictid)
                {
                    throw new Exception("此路面结构不存在" + Common.C_Enum.LayerEnum.L30.GetEnumDescription());
                }
                else if (Common.C_Enum.LayerEnum.L45.GetEnumValue() == layerDictid)
                {
                    throw new Exception("此路面结构不存在" + Common.C_Enum.LayerEnum.L45.GetEnumDescription());
                }
                else if (Common.C_Enum.LayerEnum.L50.GetEnumValue() == layerDictid)
                {
                    throw new Exception("此路面结构不存在" + Common.C_Enum.LayerEnum.L50.GetEnumDescription());
                }
                else if (Common.C_Enum.LayerEnum.L55.GetEnumValue() == layerDictid)
                {
                    throw new Exception("此路面结构不存在" + Common.C_Enum.LayerEnum.L55.GetEnumDescription());
                }
                else if (Common.C_Enum.LayerEnum.L75.GetEnumValue() == layerDictid)
                {
                    throw new Exception("此路面结构不存在" + Common.C_Enum.LayerEnum.L75.GetEnumDescription());
                }
            }
        }

        /// <summary>
        /// 返回有冲突的路面结构对象集合
        /// </summary>
        /// <param name="rdid"></param>
        /// <param name="dir"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        private List<B_Pmstc> GetClashPMSTC(string rdid, string dir, double start, double end)
        {
            IEnumerable<B_Pmstc> original = this.Scene.Bll.B_History.GetPMSTC<B_Pmstc>(rdid, Convert.ToInt32(dir));

            List<B_Pmstc> histroyStruid = new List<B_Pmstc>();
            //遍历排序后的路面结构
            foreach (B_Pmstc old in original)
            {
                if (old.Beginmp >= start && old.Endmp <= end)
                { histroyStruid.Add(old); }
                else if (old.Beginmp < start && old.Endmp > end)
                { histroyStruid.Add(old); }
                else if ((old.Beginmp == start && old.Endmp > end) ||
                                        ((end > old.Beginmp && end < old.Endmp) && start < old.Beginmp))
                { histroyStruid.Add(old); }
                else if ((old.Beginmp < start && old.Endmp == end) ||
                                       ((start > old.Beginmp && start < old.Endmp) && end > old.Endmp))
                { histroyStruid.Add(old); }

            }
            return histroyStruid;

        }
        #endregion

        #endregion


        [Route("update")]
        public IHttpActionResult UpdateB_invntory(string rdid, string dir, string start, string end, string v,string yh)
        {
            try
            {
                if (int.Parse(yh) == (int)Common.C_Enum.MainTypeEnum.M12001)
                {
                    string[] vs = v.Substring(0, v.Length - 1).Split('|');//包括层类型*铣刨厚度*加铺厚度*加铺材料
                   string[] vsStru_id =vs[0].Split('*');
                   
                    this.Scene.Bll.B_History.UpdatePreventModel(rdid, Convert.ToDouble(start), Convert.ToDouble(end), int.Parse(dir), vsStru_id[vsStru_id.Length - 1]);
                    
                }

                this.Scene.Bll.B_Invntory.DivideRoad(rdid, int.Parse(dir));

                //STHPMS1.BLL.B_Bus.B_InvntoryBus ib = new BLL.B_Bus.B_InvntoryBus();
                //ib.DivideRoad(rdid, int.Parse(dir));
                return Ok("ok");
            }
            catch(Exception ex)
            {
                var response = new HttpResponseMessage(HttpStatusCode.InternalServerError)
                {
                    Content = new StringContent(ex.Message),
                    ReasonPhrase = "Server Error"
                };
                throw new HttpResponseException(response);
            }
        }
    }


    class LayerTemp
    {
        /// <summary>
        /// 层位
        /// </summary>
        public int LAYER_DICTID { get; set; }
        /// <summary>
        /// 铣刨厚度
        /// </summary>
        public double XPTHICK { get; set; }
        /// <summary>
        /// 加铺厚度
        /// </summary>
        public double JPTHICK { get; set; }
        /// <summary>
        /// 加铺材料
        /// </summary>
        public string JPCL { get; set; }
    }
}